package com.yachang.qym.usbhost.utils;


import com.yachang.qym.usbhost.model.AreaModel;
import com.yachang.qym.usbhost.model.CalledModel;
import com.yachang.qym.usbhost.model.ContactID;
import com.yachang.qym.usbhost.model.ContactModel;
import com.yachang.qym.usbhost.model.HelpModel;
import com.yachang.qym.usbhost.model.MachineInfoModel;
import com.yachang.qym.usbhost.model.RouteModel;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;


public class DataTransfer {
    public byte DataBuffer[];
    private int ReadPos=0;
    private int WritePos=0;
    private int BufferLen=0;
    private int DataLen=0;

    public DataTransfer(int mBufferLen){
        DataBuffer=new byte[mBufferLen];
        BufferLen=mBufferLen;
    }

    public void AddData(byte mbyte) {
        DataBuffer[WritePos]=mbyte;
        WritePos++;
        if(DataLen<BufferLen){
            DataLen++;
        }
        if(WritePos==BufferLen){
            WritePos=0;
        }
    }
    public void AddData(byte []mbyte,int len){
        int i;
        for(i=0;i<len;i++){
            AddData(mbyte[i]);
        }
    }
    public byte ReadData(){
        if(DataLen==0){
            return 0;
        }
        byte mbyte=DataBuffer[ReadPos];
        return mbyte;
    }
    public byte ReadData(int Index){
        if(DataLen<=Index){
            return 0;
        }
        byte mbyte=DataBuffer[(ReadPos+Index)%BufferLen];
        return mbyte;
    }
    public int DeleteFrontData(){
        if(DataLen==0){
            return 0;
        }
        ReadPos++;
        DataLen--;
        if(ReadPos==BufferLen){
            ReadPos=0;
        }
        return 1;
    }
    public int GetDataLen(){
        return DataLen;
    }

    public int ReadMultiData(byte [] mbuffer,int Len){
        if(Len>DataLen){
            return 0;
        }

        int i;
        for(i=0;i<Len;i++){
            mbuffer[i]=ReadData();
            DeleteFrontData();
        }
        return 1;
    }

    public static byte[] intToBytes( int value )
    {
        byte[] src = new byte[4];
        src[1] =  (byte) ((value>>8) & 0xFF);
        src[0] =  (byte) (value & 0xFF);
        return src;
    }

    public static long bytesToInt(byte[] src) {
        long value;
        int byte0 = (int) src[0] > 0 ? (int) src[0] : (int) src[0] + 256;
        int byte1 = (int) src[1] > 0 ? (int) src[1] : (int) src[1] + 256;
        int byte2 = (int) src[2] > 0 ? (int) src[2] : (int) src[2] + 256;
        value = byte0 * 256 * 256 + byte1 * 256 + byte2;
        return value;
    }

    public static String Byte2Unicode(byte abyte[], int st, int bEnd) // 不包含bEnd
    {
        StringBuffer sb = new StringBuffer("");
        if( bEnd % 2 == 1){
            bEnd = bEnd - 1;
        }
        for(int j = st; j < bEnd; )
        {
            int lw = abyte[j++];
            if (lw < 0) lw += 256;
            int hi = abyte[j++];
            if (hi < 0) hi += 256;
            char c = (char)(lw + (hi << 8));
            sb.append(c);
        }
        return sb.toString();
    }

    public static String convert(byte[] data) throws UnsupportedEncodingException {
        String utfString = Byte2Unicode(data, 0, data.length);
        char aChar;
        int len = utfString.length();
        StringBuffer outBuffer = new StringBuffer(len);
        for (int x = 0; x < len;) {
            aChar = utfString.charAt(x++);
            if (aChar == '\\') {
                aChar = utfString.charAt(x++);
                if (aChar == 'u') {
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = utfString.charAt(x++);
                        switch (aChar) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                value = (value << 4) + aChar - '0';
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                value = (value << 4) + 10 + aChar - 'a';
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                value = (value << 4) + 10 + aChar - 'A';
                                break;
                            default:
                                throw new IllegalArgumentException(
                                        "Malformed   \\uxxxx   encoding.");
                        }

                    }
                    outBuffer.append((char) value);
                } else {
                    if (aChar == 't')
                        aChar = '\t';
                    else if (aChar == 'r')
                        aChar = '\r';
                    else if (aChar == 'n')
                        aChar = '\n';
                    else if (aChar == 'f')
                        aChar = '\f';
                    outBuffer.append(aChar);
                }
            } else
                outBuffer.append(aChar);
        }
       return outBuffer.toString();
    }

    public static int getNowRoute(byte[] route) throws  UnsupportedEncodingException{ //返回当前信道信息
        int routeID = (int) route[7] - 1;
        return routeID;
    }

    public static List<RouteModel> getDMRRoute(List<byte[]> byteRouteList) throws UnsupportedEncodingException {  //返回DMR信道信息
        List<RouteModel> models = new ArrayList<RouteModel>();
        //Realm myRealm = Realm.getInstance(UsbApplication.getContext());
        for(int i = 0; i < byteRouteList.size(); i++){
            RouteModel model = new RouteModel();
            byte[] br = new byte[38];
            for(int j = 0; j < 38; j++){
                if((int) (byteRouteList.get(i))[j+10] == 0 && (int) (byteRouteList.get(i))[j+11] == 0){
                    break;
                }
                br[j] = (byteRouteList.get(i))[j + 10];
            }
            model.setName(convert(br));
            model.setID((int) byteRouteList.get(i)[7]);
            model.setCallerID((int) byteRouteList.get(i)[72]);
            model.setCalledsID((int) byteRouteList.get(i)[74]);
            if((int) byteRouteList.get(i)[78] == 1){
                model.setPower(true);
            }else {
                model.setPower(false);
            }
            /*myRealm.beginTransaction();
            RouteModel copyOfRouteModel = myRealm.copyToRealm(model);
            myRealm.commitTransaction();*/
            models.add(model);
        }
        return models;
    }

    public static List<AreaModel> getAreaList(List<byte[]> byteAreaList) throws UnsupportedEncodingException { //返回区域列表
        List<AreaModel> models = new ArrayList<>();
        //Realm myRealm = Realm.getInstance(UsbApplication.getContext());
        for(int i = 0; i < byteAreaList.size(); i++){
            AreaModel model = new AreaModel();
            byte[] br = new byte[38];
            for(int j = 0; j < 38 ; j++){
                if((int) (byteAreaList.get(i))[j+10] == 0 && (int) (byteAreaList.get(i))[j+11] == 0){
                    break;
                }
                br[j] = byteAreaList.get(i)[10 + j];
            }
            model.setAreaId(convert(br));
            model.setAreaLong((int) byteAreaList.get(i)[47]);
            List<RouteModel> routes = new ArrayList<>();
            for(int j = 49; j < 49 + ((int) byteAreaList.get(i)[47]) * 3; j = j + 3){
                if((int) (byteAreaList.get(i))[j] == 0 && (int) (byteAreaList.get(i))[j+1] == 0){
                    break;
                }
                RouteModel routeModel = new RouteModel();
                for(int k = 0; k < AllData.routeModels.size(); k++){
                    if((int) byteAreaList.get(i)[j + 2] == AllData.routeModels.get(k).getID()){
                        routeModel = AllData.routeModels.get(k);
                    }
                }
                routes.add(routeModel);
            }
            model.setRoutes(routes);
            //AreaModel copyModel = myRealm.copyToRealm(model);
            models.add(model);
        }
        return  models;
    }

    public static List<CalledModel> getCalledsList(List<byte[]> byteCalledList) throws UnsupportedEncodingException {  //返回DMR接收组列表
        List<CalledModel> calledModels = new ArrayList<CalledModel>();
        //Realm myRealm = Realm.getInstance(UsbApplication.getContext());
        for(int i = 0; i < byteCalledList.size(); i++){
            CalledModel model = new CalledModel();
            model.setCalledID((int) byteCalledList.get(i)[7]);
            model.setCalledSize((int) byteCalledList.get(i)[47]);
            byte[] br = new byte[38];
            for(int j = 0; j < 38; j++) {
                if((int) (byteCalledList.get(i))[j+10] == 0 && (int) (byteCalledList.get(i))[j+11] == 0){
                    break;
                }
                br[j] = byteCalledList.get(i)[j + 10];
            }
            model.setName(convert(br));
            List<ContactID> contactID = new ArrayList<>();
            for(int j = 0; j < model.getCalledSize(); j++){
                ContactID id = new ContactID();
                id.setContactID((int) byteCalledList.get(i)[j + 49]);
                contactID.add(id);
            }
            model.setContactID(contactID);
            //CalledModel copyModel = myRealm.copyToRealm(model);
            calledModels.add(model);
        }
        return calledModels;
    }

    public static List<ContactModel> getContactList(List<byte[]> byteContactList) throws UnsupportedEncodingException{  //返回联系人列表
        List<ContactModel> contactList = new ArrayList<ContactModel>();
        for(int i = 0; i < byteContactList.size(); i++){
            ContactModel model = new ContactModel();
            model.setContactID((int) byteContactList.get(i)[7]);
            byte[] br = new byte[38];
            for (int j = 0; j < 38; j++){
                if((int) (byteContactList.get(i))[j+10] == 0 && (int) (byteContactList.get(i))[j+11] == 0){
                    break;
                }
                br[j] = (byteContactList.get(i))[j+10];
            }
            model.setName(convert(br));
            switch ((int) byteContactList.get(i)[47] ){
                case 0x00: model.setStyle(0);break;
                case 0x01: model.setStyle(1);break;
                case 0x02: model.setStyle(2);break;
                default:model.setStyle(3);break;
            }
            br = new byte[4];
            for(int j = 0; j < 4; j ++){
                br[j] = byteContactList.get(i)[j + 49];
            }
            model.setCallID(br);
            contactList.add(model);
        }
        return contactList;
    }

    public static MachineInfoModel getMachineInfo(byte[] byteMachineInfo) throws UnsupportedEncodingException { //返回本机信息
        MachineInfoModel model = new MachineInfoModel();

        byte[] br = new byte[16];
        for(int i = 0; i < 16; i++){ //设置序列号
            br[i] = byteMachineInfo[10 + i];
        }
        model.setMachineId(new String(br, "ascii").trim());

        br = new byte[15];
        for(int i = 0; i < 15; i++){ //设置机型名称
            br[i] = byteMachineInfo[28 + i];
        }
        model.setMachineName(new String(br, "ascii").trim());

        br = new byte[15];
        for(int i = 0; i < 15; i++) { //设置机型码
            br[i] = byteMachineInfo[45 + i];
        }
        model.setMachineNumber(new String(br, "ascii").trim());

        br = new byte[15];
        for(int i = 0; i < 15; i++) { //设置主机版本
            br[i] = byteMachineInfo[79 + i];
        }
        model.setMachineVersion(new String(br, "ascii").trim());

        br = new byte[36];
        for(int i = 0; i < 36; i++) { //设置本机别名
            br[i] = byteMachineInfo[99 + i];
        }
        model.setMachineOtherName(convert(br).trim());

        model.setAreaID((int) byteMachineInfo[208]);
        return model;
    }

    public static String getMachineId(byte[] byteMachineId) throws UnsupportedEncodingException {
        byte[] byteMachineID = new byte[4];
        for(int i = 10; i < 14; i ++){
            byteMachineID[i - 10] = byteMachineId[i];
        }
        return getTenNum(byteMachineID) + "";
    }

    public static long getTenNum(byte[] data){
        long sum = 0;
        for(int i = 0; i < data.length; i ++){
            long num = ((int) data[i]) > 0 ? ((int) data[i]) : ((int) data[i]) + 256;
            if(num < 10){
                num = num;
            }
            else {
                num = num / 8 * 5 + num % 16;
            }
            for(int j = i + 1; j < data.length; j++){
                num = num * 100;
            }

            sum = sum + num;
        }
        return sum;
    }

    public static HelpModel getHelpInfo(byte[] byteHelpInfo, int style) throws UnsupportedEncodingException { //返回本机高度和搜救信息
        HelpModel model = new HelpModel();
        if(style == 0) {
            HelpModel.isWhat = 0;
            byte[] byteMachineID = new byte[3];
            int count;
            for (count = 8; count < 11; count++) {
                byteMachineID[count - 8] = byteHelpInfo[count];
            }
            model.setMachineID(bytesToInt(byteMachineID) + ""); //设置本机ID；

            byte[] byteMachineTemp = getHelpInfoByte(byteHelpInfo, count, 0x43);
            count = count + byteMachineTemp.length;
            model.setMachineTemp(new String(byteMachineTemp, "ascii").trim());//设置本机温度

            byte[] byteMachinePress = getHelpInfoByte(byteHelpInfo, count, 0x50);
            count = count + byteMachinePress.length;
            model.setMachinePressure(new String(byteMachinePress, "ascii").trim());//设置本机气压

            byte[] byteMachineHigh = getHelpInfoByte(byteHelpInfo, count, 0x6D);
            count = count + byteMachineHigh.length;
            model.setMachineHigh(new String(byteMachineHigh, "ascii").trim());//设置本机高度

            if ((byteHelpInfo[count++] == 0x01)) {
                HelpModel.isWhat = 2;
                byte[] byteHelpID = new byte[3];
                for (int i = 0; i < 3; i++) {
                    byteHelpID[i] = byteHelpInfo[count++];
                }
                model.setHelpID(bytesToInt(byteHelpID) + ""); //设置呼救机ID

                byte[] byteHelpTemp = getHelpInfoByte(byteHelpInfo, count, 0x43);
                count = count + byteHelpTemp.length;
                model.setHelpTemp(new String(byteHelpTemp, "ascii").trim());//设置呼救机温度

                byte[] byteHelpPressure = getHelpInfoByte(byteHelpInfo, count, 0x50);
                count = count + byteHelpPressure.length;
                model.setHelpPressure(new String(byteHelpPressure, "ascii").trim());//设置呼救机气压

                byte[] byteHelpHigh = getHelpInfoByte(byteHelpInfo, count, 0x6D);
                count = byteHelpHigh.length + count;
                model.setHelpHigh(new String(byteHelpHigh, "ascii").trim());//设置呼救机高度

                if(!((byteHelpInfo[count] == 0x0D) && (byteHelpInfo[count + 1] == 0x0A))) {
                    count = count + 2;

                    byte[] byteHelpError = getHelpInfoByte(byteHelpInfo, count, 0x54);
                    count = count + byteHelpError.length + 2;
                    model.setHelpError(new String(byteHelpError, "ascii").trim());//error

                    byte[] byteHelpDistance = getHelpInfoByte(byteHelpInfo, count, 0x6D);
                    model.setHelpDistance(new String(byteHelpDistance, "ascii").trim());//设置与呼救机的距离
                }else {
                    model.setHelpError("");//error
                    model.setHelpDistance("");//设置与呼救机的距离
                }
            }
        }else {
            HelpModel.isWhat = 1;
            byte[] byteMachineID = new byte[3];
            int count;
            for (count = 8; count < 11; count++) {
                byteMachineID[count - 8] = byteHelpInfo[count];
            }
            model.setHelpID(bytesToInt(byteMachineID) + ""); //设置呼救机ID；

            byte[] byteHelpTemp = getHelpInfoByte(byteHelpInfo, count, 0x43);
            count = count + byteHelpTemp.length;
            model.setHelpTemp(new String(byteHelpTemp, "ascii").trim());//设置呼救机温度

            byte[] byteHelpPressure = getHelpInfoByte(byteHelpInfo, count, 0x50);
            count = count + byteHelpPressure.length;
            model.setHelpPressure(new String(byteHelpPressure, "ascii").trim());//设置呼救机气压

            byte[] byteHelpHigh = getHelpInfoByte(byteHelpInfo, count, 0x6D);
            model.setHelpHigh(new String(byteHelpHigh, "ascii").trim());//设置呼救机高度
            count = byteHelpHigh.length + count;

            if(!((byteHelpInfo[count] == 0x0D) && (byteHelpInfo[count + 1] == 0x0A))) {
                count = count + 2;

                byte[] byteHelpError = getHelpInfoByte(byteHelpInfo, count, 0x54);
                count = count + byteHelpError.length + 2;
                model.setHelpError(new String(byteHelpError, "ascii").trim());//error

                byte[] byteHelpDistance = getHelpInfoByte(byteHelpInfo, count, 0x6D);
                model.setHelpDistance(new String(byteHelpDistance, "ascii").trim());//设置与呼救机的距离
            }else {
                model.setHelpError("");//error
                model.setHelpDistance("");//设置与呼救机的距离
            }
        }
        return model;
    }

    public static String getDebugData(byte[] data){
        String str = "";
        for(int i= 7; ;i++){
            if(data[i] == 0x0D && data[i + 1] == 0x0A){
                break;
            }else {
                int whatData = ((int) data[i]) > 0 ? ((int) data[i]) : ((int) data[i]) + 256;
                str = str + Integer.toHexString(whatData) + " ";
            }
        }
        return str;
    }

    public static byte[] getHelpInfoByte(byte[] data, int count, int style){
        byte[] byteCache = new byte[32];
        int mpl = 0;
        for( ; ; count ++){
            int byteData = (int) (data[count]) > 0 ? (int) (data[count]) : 256 + (int) (data[count]);
            if(byteData == style) {
                break;
            }else {
                byteCache[mpl++] = data[count];
            }
        }
        byte[] byteContent = new byte[mpl + 1];
        for(int i = 0; i <= mpl ; i++){
            byteContent[i] = byteCache[i];
        }
        return byteContent;
    }

    public static double getNum(String str){
        char[] b = str.toCharArray();
        String result = "";
        for (int i = 0; i < b.length; i++) {
            if (("0123456789.-").indexOf(b[i] + "") != -1) {
                result += b[i];
            }
        }
        if(result.equals("")){
            return 0;
        }
        return Double.valueOf(result).doubleValue();
    }

    public static boolean byteEquals(byte[] a, byte[] a2) {
        if (a==a2)
            return true;
        if (a==null || a2==null)
            return false;
        int length = a.length;
        if (a2.length != length)
            return false;
        for (int i=0; i<length; i++)
            if (a[i] != a2[i])
                return false;
        return true;
    }

}
